package com.common.base.widget

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.animation.AnimationSet
import android.view.animation.Interpolator
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.common.base.R
import com.common.base.app.extras.otherwise
import com.common.base.app.extras.yes
import com.common.base.manager.AutoLayoutManager
import com.common.base.manager.XLinearLayoutManager
import com.google.android.flexbox.FlexboxLayoutManager

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：3/2/2023
 *
 * 描述：自定义RecyclerView<br></br>
 *
 * 修订历史：
 *
 */
open class HeaderRecyclerView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet?,
    defStyle: Int = 0
) :
    RecyclerView(context, attrs, defStyle) {
    /**
     * 标题栏
     */
    private var titleBar: View? = null

    /**
     * 标题文字
     */
    private var titleTv: TextView? = null

    /**
     * 副标题文字
     */
    private var subTitleTv: TextView? = null

    /**
     * 动画器
     */
    private val animator: AnimationSet? = null

    /**
     * 标题栏正常高度
     */
    private var tHeight = 0

    /**
     * 标题栏展开高度
     */
    private var tExpendHeight = 0

    /**
     * 正常高度于展开高度的差
     */
    private var tOffset = 0

    /**
     * 布局对象
     */
    private var llm: LayoutManager? = null

    /**
     * 监听器
     */
    private var listener: OnHeaderListViewListener? = null

    /**
     * 有滑动头部
     */
    private var hasHeader = false

    /**
     * 1线性纵向2网格0线性横向
     */
    private var layoutStyle = 0

    /**
     * 网格布局默认数量
     */
    private var gridLayoutNum = 2

    private var notTouch = false

    /**
     * 动画拦截器,用于控制动画进度
     */
    private val myInterpolator = Interpolator {
        val offset = titleBar!!.height - tHeight

        // 高度为0时直接返回1f
        if (0 == offset) {
            1f
        } else (tOffset - offset) * 1f / tOffset
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(e: MotionEvent?): Boolean {
        return if (notTouch) false else super.onTouchEvent(e)// 判断是否需要禁止传递触摸事件
    }

    /**
     * [简要描述]:构造函数<br></br>
     * [详细描述]:构造函数<br></br>
     *
     * @param context  上下文对象
     * @param attrs    属性表
     * @param defStyle 样式
     */
    /**
     * [简要描述]:构造函数<br></br>
     * [详细描述]:构造函数<br></br>
     *
     * @param context 上下文对象
     * @param attrs   属性表
     */
    init {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.HeaderRecyclerView)

        // 属性不能为空
        if (attrs == null) {
            throw RuntimeException(resources.getString(R.string.attr_not_null))
        } else {
            // 构建
            layoutStyle = typedArray.getInt(R.styleable.HeaderRecyclerView_set_layout_style, layoutStyle)
            gridLayoutNum = typedArray.getInt(R.styleable.HeaderRecyclerView_grid_layout_num, gridLayoutNum)
            typedArray.getBoolean(R.styleable.HeaderRecyclerView_close_item_animator, false).yes {
                itemAnimator = null
            }.otherwise {
                itemAnimator = DefaultItemAnimator()
            }
            notTouch = typedArray.getBoolean(R.styleable.HeaderRecyclerView_not_touch, false)
            typedArray.recycle()
        }
        init(context)
    }

    /**
     * [简要描述]:设置头部参数<br></br>
     * [详细描述]:设置头部参数<br></br>
     *
     * @param tb  标题栏
     * @param tv  标题文本
     * @param stv 副标题文本
     * @param th  正常高度
     * @param te  展开高度
     */
    fun setHeader(tb: View?, tv: TextView?, stv: TextView?, th: Int, te: Int) {
        titleBar = tb
        titleTv = tv
        subTitleTv = stv
        tHeight = th
        tExpendHeight = te
        tOffset = te - th
        setPadding(0, tOffset, 0, 0)
        val lp = this.layoutParams as RelativeLayout.LayoutParams
        lp.topMargin = th
        this.layoutParams = lp
        unExpendAnimation()
        hasHeader = true
    }

    /**
     * [简要描述]:设置监听器<br></br>
     * [详细描述]:设置监听器<br></br>
     *
     * @param l 监听器
     */
    fun setOnHeaderListViewListener(l: OnHeaderListViewListener?) {
        listener = l
    }

    /**
     * [简要描述]:初始化<br></br>
     * [详细描述]:初始化<br></br>
     *
     * @param ctx 上下文对象
     */
    private fun init(ctx: Context) {
        llm = if (layoutStyle == 1) {
            XLinearLayoutManager(ctx, LinearLayoutManager.HORIZONTAL, false)
        } else if (layoutStyle == 2) {
            GridLayoutManager(ctx, gridLayoutNum)
        } else if (layoutStyle == 3) {
//            AutoLayoutManager()
            FlexboxLayoutManager(ctx)
        } else {
            XLinearLayoutManager(ctx, LinearLayoutManager.VERTICAL, false)
        }
        layoutManager = llm
        setOnScrollListener(MyOnScrollListener())

        notTouch.yes { isNestedScrollingEnabled = false }//禁止滑动
    }

    /**
     * [简要描述]:获取当前子项的总高度<br></br>
     * [详细描述]:获取当前子项的总高度<br></br>
     *
     * @param count 数值
     * @return 总高度
     */
    fun getItemTotalHeight(count: Int): Int {
        if (count == 0) {
            return 0
        }
        val view = getChildAt(0) ?: return 0

        // 布局为空则返回零
        return view.height * count
    }

    /**
     * [简要描述]:获取管理器<br></br>
     * [详细描述]:获取管理器<br></br>
     *
     */
    fun getLinearLayoutManager(): LinearLayoutManager? {
        return llm as LinearLayoutManager
    }

    fun setLinearLayoutManager(lm:LinearLayoutManager){
        llm = lm
        layoutManager = llm
    }

    private fun unExpendAnimation() {

//        // 缩小后的标题文字尺寸
//        int smailSize = getContext().getResources().getDimensionPixelSize(R.dimen.font_size_title);
//
//        // 放大后的标题文字尺寸
//        int bigSize = getContext().getResources().getDimensionPixelSize(R.dimen.wallet_expend_title_size);
//
//        // 标题内边距
//        int titlePadding = getContext().getResources().getDimensionPixelSize(R.dimen.space_large);
//
//        // 缩小后文字宽度
//        float smallWidth = DisplayUtil.getTextWidth(titleTv.getText().toString(), smailSize, false);
//
//        // 放大后文字宽度
//        float bigWidth = DisplayUtil.getTextWidth(titleTv.getText().toString(), bigSize, false);
//
//        // 放大后文字高度
//        int bigHeight = DisplayUtil.getTextHeight(titleTv.getText().toString(), bigSize, false);
//
//        // 缩小比例
//        float scale = smallWidth / bigWidth;
//
//        // 屏幕宽度
//        int screenWidth = DisplayUtil.getScreenWidth(getContext());
//
//        animator = new AnimationSet(true);
//        animator.setInterpolator(myInterpolator);
//
//        animator.setFillEnabled(true);
//        animator.setFillAfter(true);
//
//        ScaleAnimation scaleAnima = new ScaleAnimation(1f, scale, 1f, scale, Animation.RELATIVE_TO_SELF,
//                RELATIVE_TO_SELF_HALF, Animation.RELATIVE_TO_SELF, RELATIVE_TO_SELF_HALF);
//        animator.addAnimation(scaleAnima);
//
//        TranslateAnimation translateAnima = new TranslateAnimation(0, (screenWidth - bigWidth) / 2 - titlePadding, 0,
//                -tHeight + (tHeight - bigHeight) / 2);
//        animator.addAnimation(translateAnima);
//        titleTv.startAnimation(animator);
//
//        AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0f);
//        alphaAnimation.setInterpolator(myInterpolator);
//        alphaAnimation.setFillEnabled(true);
//        alphaAnimation.setFillAfter(true);
//        subTitleTv.startAnimation(alphaAnimation);
    }

    /**
     * [简要描述]:修改头部高度<br></br>
     * [详细描述]:修改头部高度<br></br>
     *
     * @param hOffset 高度
     */
    private fun changeTitleHeight(hOffset: Int): Boolean {
        val lp = titleBar!!.layoutParams as RelativeLayout.LayoutParams
        var height = tExpendHeight - hOffset
        height = Math.max(height, tHeight)
        lp.height = height
        titleBar!!.layoutParams = lp
        return height == tHeight
    }

    /**
     * [简要描述]:滚动处理器<br></br>
     * [详细描述]:滚动处理器<br></br>
     */
    internal inner class MyOnScrollListener : OnScrollListener() {
        /**
         * 表示头部隐藏了
         */
        private var isHeadHide = false

        /**
         * 滚动条位置
         */
        private var scrollY = 0

        /**
         * [简要描述]:重置滚动状态<br></br>
         * [详细描述]:重置滚动状态<br></br>
         */
        fun reset() {
            scrollY = 0
        }

        /**
         * [简要描述]:滚动事件<br></br>
         * [详细描述]:滚动事件<br></br>
         *
         * @param recyclerView 列表控件
         * @param newState     滚动状态
         * @throws
         * @see OnScrollListener.onScrollStateChanged
         */
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            when (newState) {
                SCROLL_STATE_IDLE ->
                    // 检查是否需要加载下一页
                    if (listener != null) {
                        listener!!.stopScroll()
                    }
                SCROLL_STATE_DRAGGING -> {}
                SCROLL_STATE_SETTLING -> {}
            }
            super.onScrollStateChanged(recyclerView, newState)
        }

        /**
         * [简要描述]:滚动事件<br></br>
         * [详细描述]:监听滚动事件<br></br>
         *
         * @param recyclerView 布局
         * @param dx           布局
         * @param dy           开始位置
         * @throws
         * @see OnScrollListener.onScrolled
         */
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            val childCount = recyclerView.childCount
            if (childCount == 0) {
                return
            }
            if (listener != null) {
                listener!!.mLastVisibleItemPosition((llm as LinearLayoutManager).findLastVisibleItemPosition())
            }

            // 检查是否需要加载下一页
            if (listener != null && !listener!!.isDataLoading) {
                localLoadCheck()
            }

            // 未设置头部，则不处理下面逻辑
            if (!hasHeader) {
                return
            }
            scrollY += dy

            // 如果目前处于第一项,则使头部跟随第一项移动
            if (scrollY <= tOffset) {
                isHeadHide = changeTitleHeight(scrollY)
            } else if (!isHeadHide) {
                isHeadHide = changeTitleHeight(scrollY)
            }
        }

        /**
         * 局部加载检查 如果当前滚动到最后一项了,则加载下一页数据
         */
        private fun localLoadCheck() {
            // 取得当前最后一个可视的item
            val lastVisiblePostion = (llm as LinearLayoutManager).findLastVisibleItemPosition()

            // 如果最后可视item就是列表的最后一项,则加载下一页数据
            if (lastVisiblePostion == listener!!.itemCount - 1) {
                listener!!.onNextPage()
            }
        }
    }

    /**
     * [简要描述]:监听器<br></br>
     * [详细描述]:监听器<br></br>
     */
    interface OnHeaderListViewListener {
        /**
         * [简要描述]:获取子项数量<br></br>
         * [详细描述]:获取子项数量<br></br>
         *
         * @return 子项数量
         */
        val itemCount: Int

        /**
         * [简要描述]:加载下一页<br></br>
         * [详细描述]:加载下一页<br></br>
         *
         * @return 是否有下一页
         */
        fun onNextPage(): Boolean

        /**
         * [简要描述]:获取数据加载状态<br></br>
         * [详细描述]:获取数据加载状态<br></br>
         *
         * @return true正在加载, false加载完毕
         */
        val isDataLoading: Boolean

        /**
         *
         */
        fun stopScroll()

        /**
         *
         */
        fun mLastVisibleItemPosition(mPosition: Int)
    }

    companion object {
        /**
         * 相对位置
         */
        const val RELATIVE_TO_SELF_HALF = 0.5f

        /**
         * 用于判断上下滑动
         */
        const val OFFSET = 10
    }
}